<?php

class HTMLStudioEngine
{
	/**
	 * Context
	 *
	 * @var Context
	 */
	protected $context;
	
	
	/**
	 * Engine do FW
	 *
	 * @param Context $context
	 * @return HTMLStudioEngine
	 */
	public function HTMLStudioEngine($context)
	{
		$this->context = $context;	
	}	
	
	public function BuildPageFromModule()
	{

		$module = $this->getModule();		
		$method = $this->context->getAction();
		$paremetros = $this->context->getParameteres();
		
		$this->CheckModuleGrants($module);
		
		$rmethod = new ReflectionMethod($module, $method);
				
		if($rmethod->isPublic())
		{			
		    if($rmethod->getNumberOfParameters())
		    {  		    	
		   		$rmethod->invokeArgs($module,$paremetros);		        
		    }
		    else
		    {		    	
		        $rmethod->invoke($module);
		    }
		}
		else
		{
			throw new Exception("O método ($method) deve ser publico");
		}
		
		return $this->ProcessTemplate($module);		
	}
	
	protected function ProcessTemplate($module)
	{

        if(!$this->context->isRunatClient())
        {
            if($module->template)
            {

                $template = new AppTemplate();
                $html =  $template->processController($module,$this->context);

                $this->context->removeSession('myShowF');

                return $html;

            }
        }
        else
        {
            return json_encode($this->processControl());
        }
	}	
	
	/**
	 * 
	 * @param BaseModule $module
	 */
	protected function CheckModuleGrants($module)
	{		
		if ($module->requiresAuthentication())
		{
			if (!$this->context->IsAuthenticated())
			{				
				$module->processNotAutenticated();
			}
			else
			{			
				$module->processInsufficientPrivilege();				
			}
		}
	}
	
	/**
	 * Obtem a instancia do modulo
	 *
	 * @param string $name
	 * @return BaseModule
	 */
	public function getModule()
	{
		$module = $this->context->getModule();		
		$module = strtolower($module);
		
		if(!$this->tryLoadModule($module))
		{			
			//DebugUtil::PrintValue('nenhum modulo',"line: ".__LINE__ );
			throw new ModuleExecption("Módulo \"$module\" não encontrado.");
		}
		
		// instanciando modulo
		$class = new ReflectionClass($this->context->getController()."controller");
		$result = $class->newInstance();
				
		$uses = array_merge($result->uses, $result->usesRoot);
		foreach ($uses as $name)
		{		
			include_once($this->context->PathModel() . strtolower($name)."_model.php");
			$classModel = new ReflectionClass($name."model");			
			$resultModel = $classModel->newInstance();
			$result->{ucwords($name)} = $resultModel;			
		}
		
		$comps = array_merge($result->comp, $result->compRoot);
		foreach ($comps as $comp)
		{
			include_once($this->context->PathComponentes() . $comp.".php");
		}
		
		$result->Setup();
				
		return $result;
	}
	
	public function tryLoadModule($module)
	{		
		$arrModule = explode('.', $module);
		$name = array_pop($arrModule);
		$path = implode(FileUtil::Slash(), $arrModule);

		$moduleToLoad = $this->context->getDirController() .FileUtil::Slash(). $path . FileUtil::Slash() . $name ."_controller.php";		
		
		//DebugUtil::PrintValue($moduleToLoad,"line: ".__LINE__  . 'CLass' . __CLASS__);
		
		$this->context->setController($name);		
		$found = file_exists($moduleToLoad);		
		if ($found)
		{			
			include_once($moduleToLoad);
		}		
		return $found;
	}

    private function processControl()
    {
        $controles = array();
        if(count($this->context->getControl()))
        {
            foreach($this->context->getControl() as $control)
            {
                $controles[] = $control->_Attributes;
            }
        }
        return $controles;
    }
}

?>